#pragma once

#include <iostream>
#include <sys/wait.h>
#include <functional>
#include "Log.hpp"
#include "Common.hpp"
#include "InetAddr.hpp"
#include "socket.hpp"
namespace TcpServerMoudule
{
    using namespace LogMoudule;
    using namespace SocketMoudule;
    using tcphandle_t = std::function<bool(SockPtr, InetAddr *)>;
    class TcpServer
    {
    public:
        TcpServer(int port)
            : _listensockp(std::make_unique<TcpSocket>()),
              _port(port),
              _isrunning(false)
        {
        }
        void InitServer(tcphandle_t handler)
        {
            _handler=handler;
            _listensockp->BulidTcpSocketMethod(_port);
        }
        void Loop()
        {
            _isrunning = true;
            while (_isrunning)
            {
                InetAddr clientaddr;
                auto sockfd = _listensockp->Accepter(&clientaddr);
                if (sockfd < 0)
                    continue;
                LOG(LogLevel::DEBUG) << "get a new client, sockfd is " << sockfd->Fd();

                pid_t pid = fork();
                if (pid == 0)
                {
                    _listensockp->Close();
                    if (fork() > 0)
                        exit(0);
                    //交给上层
                    _handler(sockfd,&clientaddr);
                    exit(0);
                }
                sockfd->Close();
                int rid = ::waitpid(pid, nullptr, 0);
            }
        }
        ~TcpServer()
        {
            _listensockp->Close();
        }

    private:
        std::unique_ptr<Socket> _listensockp;
        int _port;
        bool _isrunning;
        tcphandle_t _handler;
    };

}